package com.bradz.mytv;

import java.util.ArrayList;
import java.util.Random;

import android.content.Context;
import android.text.format.Time;
import android.util.Log;


public class classNetworkHolder {
	private classChannelDatabase channel_database;
	private int current_channel;
	private boolean skip_flag;
	private boolean is_commercial;
	private Context context;
	private ArrayList<classChannelHolder> channels = new ArrayList<classChannelHolder>();
	private classSettingsHolder settings;
	private Time network_time;
	private classCommercialParser commercialHolder;
	private Random randomGen;
	private String set_commercial;
	public boolean not_initialized = true;
	//private boolean save_flag;
	
	classNetworkHolder(Context context, boolean async_load, Random randomGen){
		this.context = context;
		this.randomGen = randomGen;
		initialize(this.context,async_load);
	}
	
	classNetworkHolder(Context context){
		this.context = context;
		initialize(this.context,false);
	}
	
	public void initialize(Context context, boolean async_load){
		channel_database = new classChannelDatabase(context);
		settings = new classSettingsHolder(channel_database.get_settings());
		network_time = new Time();
		network_time.setToNow();
		//We are going to skip over this step so that we can keep track
		//of the progress bar
		if(!async_load){
			check_mounted_files();
		}
		//If there are no channels, we will be unable to set the current episode
		//This isn't perfect yet. Needs to be put into the next release instead
		settings.commercials = false;
		is_commercial = false;
		/*if(settings.commercials && channel_database.get_all_commercials_in_database().size() < 1){
			new classFetchInternet().execute("http://www.reddit.com/r/videos+music/.json?sort=rising&limit=100",context);
		}*/
		
		skip_flag = false;
		not_initialized = false;
	}
	
	public void check_mounted_files(){
		ArrayList<Integer> channel_numbers = new ArrayList<Integer>(channel_database.get_all_channels());
		ArrayList<classRecovery> recovery_table = new ArrayList<classRecovery>(channel_database.get_recovery_table());
		channels = new ArrayList<classChannelHolder>();
		classChannelHolder channel_holder;
		for(int i = 0; i < channel_numbers.size();i++){
			channel_holder = new classChannelHolder(channel_numbers.get(i), 
					channel_database.get_channel_name(channel_numbers.get(i)), 
					channel_database.get_channel_paths(channel_numbers.get(i)),true);
			//What is the point of having a channel with no episodes?
			if (channel_holder.channel_size() > 0){
				channels.add(channel_holder);
				//
				if (i<recovery_table.size()){
					this.channels.get(recovery_table.get(i).channel_number).get_episode(recovery_table.get(i).channel_episode);
					this.channels.get(recovery_table.get(i).channel_number).set_episode_offset(recovery_table.get(i).episode_offset);
				}
			}
		}
		current_channel = 0;
		if (channels.size()>0){
			int[] info = new int[2];
			System.arraycopy( channel_database.get_last_channel_episode(), 0, info, 0, info.length );
			if (info[0]<channels.size() && info[1]<this.channels.get(info[0]).channel_size()){
				current_channel = info[0];
				this.get_current_channel().get_episode(info[1]);
			}else{
				//If there are channels, but the last channel played is missing, schedule a random episode on channel 0
				this.get_current_channel().get_random_episode(settings.channel_scheduling);
			}
		}
	}
	
	public void async_network_update(ArrayList<classChannelHolder> channels){
		this.channels = new ArrayList<classChannelHolder>(channels);
		current_channel = 0;
		if (this.channels.size()>0){
			int[] info = new int[2];
			System.arraycopy( channel_database.get_last_channel_episode(), 0, info, 0, info.length );
			if (info[0]<this.channels.size() && info[1]<this.channels.get(info[0]).channel_size()){
				current_channel = info[0];
				this.get_current_channel().get_episode(info[1]);
			}else{
				//If there are channels, but the last channel played is missing, schedule a random episode on channel 0
				this.get_current_channel().get_random_episode(settings.channel_scheduling);
			}
		}
		Log.i("classNetworkHolder","Channel Size: " + String.valueOf(channels.size()));
	}
	
	public int add_channel_get_id(String name){
		channel_database.add_channel(name);
		return channel_database.get_channel_id(name);
	}
	
	public void setCommercials(classCommercialParser holder){
		Log.i("myTV - networkHolder", "Setting Commercials");
		commercialHolder = new classCommercialParser(holder);
		commercialHolder.print_list();
	}
	
	public void reset_recovery_database(){
		channel_database.reset_recovery_data();
	}
	
	public void set_current_time(){
		network_time.setToNow();
	}
	
	public String get_current_time(){
		return network_time.toString();
	}
	
	
	
	public boolean get_sflag(){
		return skip_flag;
	}
	
	public classSettingsHolder get_settings_holder(){
		return settings;
	}
	
	public void refresh_settings(){
		settings = new classSettingsHolder(channel_database.get_settings());
	}
	
	public void delete_channel(String channel_name){
		channel_database.delete_channel(channel_database.get_channel_id(channel_name));
		//initialize(context,false);
	}
	
	public void delete_channel_episodes(String channel_name){
		channel_database.delete_channel_episodes(channel_database.get_channel_id(channel_name));
		//initialize(context,false);
	}
	
	public void delete_single_channel_episode(int channel_number, String episode_path){
		channel_database.delete_single_channel_episode(channel_number,episode_path);
		//initialize(context,false);
	}
	
	public void add_channel_episodes(int channel_number, String episode){
		channel_database.add_channel_episodes(channel_number, episode);
		//initialize(context,false);
	}
	
	public int get_size(){
		return channels.size();
	}
	
	public void update_settings(){
		channel_database.update_settings(settings);
	}
	
	public void set_current_channel(int position){
		current_channel = position;
		if(current_channel > channels.size() || current_channel < 0){
			current_channel = 0;
		}
	}
	
	public void set_current_channel_by_database_index(int position){
		for(int i = 0; i < channels.size();i++){
			if(channels.get(i).get_channel_number() == position){
				current_channel = i;
			}
		}
	}
	
	public void set_is_commercial(boolean set){
		is_commercial = set;
	}
	
	public boolean get_is_commercial(){
		return is_commercial;
	}
	
	public String return_commercial(){
		return set_commercial;
	}
	
	public void roll_dice(int threshold){
		if (settings.commercials){
			int generated = randomGen.nextInt(100);
			Log.i("myTV - roll_dice", "generated: " + generated + " threshold: " + threshold);
			if (threshold>generated){
				ArrayList <String> commercials = channel_database.get_all_commercials_in_database();
				if (commercials.size()<1){
					is_commercial = false;
				}else{
					is_commercial = true;
					int random = randomGen.nextInt(commercials.size());
					String URL = commercials.get(random);
					set_commercial = URL;
				}
			}
		}
	}
	
	public void remove_channel_position(int index){
		if (index<channels.size()){
			channels.remove(index);
		}
	}
	
	public void remove_channel(int index){
		for(int i = 0; i < channels.size();i++){
			if(channels.get(i).get_channel_number() == index){
				channels.remove(i);
			}
		}
	}
	
	public String[] get_channel_names(){
		String[] channel_names = new String[channels.size()];
		for(int i = 0; i < channels.size();i++){
			channel_names[i] = channels.get(i).get_channel_name();
		}
		if (channel_names.length <=0){
			String[] return_value = new String[1];
			return_value[0] = "No Channels";
			return return_value;
		}
		return channel_names;
	}
	
	public void print_channel_infos(){
		for(int i = 0; i < channels.size();i++){
			Log.i("myTV - print_channel_infos", "Channel number: " + channels.get(i).get_channel_number() + " Name: " + channels.get(i).get_channel_name());
		}
	}
	
	public boolean network_empty(){
		return channels.isEmpty();
	}
	
	public classChannelHolder get_current_channel(){
		Log.i("myTV - get_current_channel", "Current_channel: " + current_channel + " Size: " + channels.size());
		return channels.get(current_channel);
	}
	
	public void save_last_episode(){
		//if(!save_flag){
		ArrayList<classRecovery> recovery_table = new ArrayList<classRecovery>();
		//This saves the current channel and episode being watched
		channel_database.set_last_channel_episode(new int[]{this.current_channel, this.get_current_channel().get_current_episode()});
		//This saves the other channels and episodes not being watched
		Log.i("myTV - save_last_episode", "Saving Episodes. Channel Size: " + channels.size());
		for(int i = 0; i < channels.size();i++){
			Log.i("myTV - save_last_episode", "Save Current Episode: " + this.channels.get(i).get_current_episode());
			//Log.i("myTV - save_last_episode", " Episode Name: " + this.channels.get(i).get_episode(this.channels.get(i).get_current_episode()));
			Log.i("myTV - save_last_episode", " Offset: " + this.channels.get(i).get_episode_offset());
			recovery_table.add(new classRecovery(i, 
					this.channels.get(i).get_current_episode(), 
					this.channels.get(i).get_episode_offset(),
					this.channels.get(i).get_episode_length()));
		}
		Log.i("myTV - save_last_episode", "End Save");
		channel_database.set_recovery_table(recovery_table);
		//	save_flag = true;
		//}
	}
	
	public void load_last_episode(){
		ArrayList<classRecovery> recovery_table = new ArrayList<classRecovery>(channel_database.get_recovery_table());
		int[] info = new int[2];
		Log.i("myTV - save_last_episode", "Loading Episodes");
		//The network needs to be reloaded here
		for(int i = 0; i < recovery_table.size();i++){
			Log.i("myTV - save_last_episode", "Load Current Episode: " + recovery_table.get(i).channel_episode + 
					" Episode Name: " + this.channels.get(recovery_table.get(i).channel_number).get_episode(recovery_table.get(i).channel_episode) +
					" Offset: " + recovery_table.get(i).episode_offset);
			this.channels.get(recovery_table.get(i).channel_number).get_episode(recovery_table.get(i).channel_episode);
			this.channels.get(recovery_table.get(i).channel_number).set_episode_offset(recovery_table.get(i).episode_offset);
		}
		Log.i("myTV - load_last_episode", "End Load");
		//This is here so that the database doesn't have to be called twice
		System.arraycopy( channel_database.get_last_channel_episode(), 0, info, 0, info.length );
		current_channel = info[0];
		get_current_channel().get_episode(info[1]);
	}
	
	public void move_up_channel(){
		//We need to turn off the show_lock when the channels are changed
		if (get_current_channel().get_show_lock()){get_current_channel().switch_show_lock();}
		current_channel++;
		if (current_channel > channels.size()-1){
			current_channel=0;
		}
		update_channel_offset();
	}
	
	public void move_down_channel(){
		//We need to turn off the show_lock when the channels are changed
		if (get_current_channel().get_show_lock()){get_current_channel().switch_show_lock();}
		current_channel--;
		if (current_channel < 0){
			current_channel=channels.size()-1;
		}
		update_channel_offset();
	}
	
	//This happens when the user selected the channel from the dropdown
	public void move_custom_channel(int channel_number){
		if (get_current_channel().get_show_lock()){get_current_channel().switch_show_lock();}
		current_channel = channel_number;
		if (current_channel < 0){
			current_channel = 0;
		}else if(current_channel > channels.size()-1){
			current_channel = channels.size()-1;
		}
		update_channel_offset();
	}
	
	public ArrayList<classChannelHolder> get_channels(){
		return channels;
	}
	
	public void drop_settings(){
		channel_database.reset_settings();
	}
	
	public classChannelDatabase get_channel_database(){
		return channel_database;
	}
	
	public void update_channel_offset(){
		Time this_time = new Time();
		this_time.setToNow();
		for(classChannelHolder chan : channels){
			int time_difference = chan.get_offset() + Time.compare(this_time, network_time);
			chan.set_offset(time_difference);
			//Log.i("mytv - time_diff: " + time_difference,"networkholder");
			//Log.i("mytv - network_diff: " + Time.compare(this_time, network_time),"networkholder");
		}
		set_current_time();
	}
}
